package org.jeecg.modules.rooms.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.modules.business.entity.BusHousePriceSchemeLayout;
import org.jeecg.modules.business.enums.CustomerTypeEnum;
import org.jeecg.modules.business.service.IBusHousePriceSchemeLayoutService;
import org.jeecg.modules.rooms.DTO.CesHousePriceSchemeDto;
import org.jeecg.modules.rooms.DTO.CesHousePriceSchemeSearchDto;
import org.jeecg.modules.rooms.Vo.CesHousePriceSchemeVo;
import org.jeecg.modules.rooms.Vo.CesHousePriceSchemesVo;
import org.jeecg.modules.rooms.entity.*;
import org.jeecg.modules.rooms.mapper.CesHousePriceSchemeMapper;
import org.jeecg.modules.rooms.mapper.CesRoomLayoutMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.Time;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 房价方案 服务实现类
 * </p>
 *
 * @author Claude
 * @since 2023-03-09
 */
@Service
public class CesHousePriceSchemeServiceImpl extends ServiceImpl<CesHousePriceSchemeMapper, CesHousePriceScheme> implements IService<CesHousePriceScheme> {

    @Resource
    CesHousePriceSchemeMapper cesHousePriceSchemeMapper;

    @Resource
    private CesRoomLayoutMapper cesRoomLayoutMapper;

    @Autowired
    private IBusHousePriceSchemeLayoutService busHousePriceSchemeLayoutService;

    public Result list(CesHousePriceSchemeSearchDto dto) {
        QueryWrapper<CesHousePriceScheme> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CesHousePriceScheme.HOTEL_ID,dto.getHotelId());
        if (StringUtils.isNotEmpty(dto.getParamName())){
            //处理百分号 mybatis plus bug 查询 % 出现全量数据
            //四个字段只要有一个模糊对应传来的参数名称就能查出来
            queryWrapper.and(wrapper->wrapper
                    .like(CesHousePriceScheme.SIMPLE_CODE, CommonUtils.escapeChar(dto.getParamName()))
                    .or()
                    .like(CesHousePriceScheme.PRICE_SCHEME, CommonUtils.escapeChar(dto.getParamName()))
                    .or()
                    .like(CesHousePriceScheme.NUMBER, CommonUtils.escapeChar(dto.getParamName())));
        }
        queryWrapper.eq(CesHousePriceScheme.SCHEME_TYPE,3);
        queryWrapper.eq(CesHousePriceScheme.INVALID,false);
        queryWrapper.orderByAsc(CesHousePriceScheme.SORT);
        IPage<CesHousePriceScheme> dataPage = cesHousePriceSchemeMapper.selectPage(new Page<>(dto.getPageNo().intValue(),dto.getPageSize().intValue()),queryWrapper);
        List<CesHousePriceScheme> records = dataPage.getRecords();
        List<CesHousePriceSchemeVo> vos = new ArrayList<>();

        records.forEach(v->{
            CesHousePriceSchemeVo vo = new CesHousePriceSchemeVo();
            BeanUtil.copyProperties(v, vo);

            vo.setGuestTypeName(vo.getGuestType() == null ? "全部" : CustomerTypeEnum.val(vo.getGuestType()).getTitle());

            DateFormat startDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            String _checkText = vo.getCheckInTime() == 0?"无限制":(vo.getStartTime().format(DateTimeFormatter.ofPattern("HH:mm"))+" - "
                    +vo.getEndTime().format(DateTimeFormatter.ofPattern("HH:mm")));
            vo.setCheckInTimeText(_checkText);
            String _validText = vo.getValidTime() == 0?"无限制":(vo.getValidStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))+" - "
                    +vo.getValidEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            vo.setValidTimeText(_validText);

//            vo.setCheckInTimeText(vo.getStartTime()+" - "+vo.getEndTime());
//            vo.setValidTimeText(vo.getValidStartTime()+" - "+vo.getValidEndTime());

            vos.add(vo);
        });
        Map<String,Object> map = new HashedMap();
        map.put("records",vos);
        map.put("total",dataPage.getTotal());
        return Result.OK(map);
    }

    public Result listEnum(CesHousePriceSchemeSearchDto dto) {
        QueryWrapper<CesHousePriceScheme> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CesHousePriceScheme.HOTEL_ID,dto.getHotelId());
        queryWrapper.eq(CesHousePriceScheme.INVALID,false);
        queryWrapper.eq(CesHousePriceScheme.SCHEME_TYPE,3);
        queryWrapper.eq(CesHousePriceScheme.OPEN,1);
        queryWrapper.and(e -> e.le(CesHousePriceScheme.VALID_START_TIME, LocalDate.now())
                .ge(CesHousePriceScheme.VALID_END_TIME, LocalDate.now()).or().eq(CesHousePriceScheme.VALID_TIME, 0));
        queryWrapper.and(e -> e.le(CesHousePriceScheme.START_TIME, LocalTime.now())
                .ge(CesHousePriceScheme.END_TIME, LocalTime.now()).or().eq(CesHousePriceScheme.CHECK_IN_TIME, 0));
//        queryWrapper.orderByAsc(CesHousePriceScheme.SORT);
        List<CesHousePriceScheme> cesHousePriceSchemes = cesHousePriceSchemeMapper.selectList(queryWrapper);
        List<String> idList = cesHousePriceSchemes.stream().map(CesHousePriceScheme :: getId).collect(Collectors.toList());
        List<CesHousePriceSchemeVo> cesHousePriceSchemeVoList = new ArrayList<>();
        if (CollUtil.isNotEmpty(idList)){
            List<BusHousePriceSchemeLayout> priceSchemeLayouts = cesHousePriceSchemeMapper.queryLayoutBySchemeId(idList);
            cesHousePriceSchemeVoList = BeanUtil.copyToList(cesHousePriceSchemes, CesHousePriceSchemeVo.class);
            cesHousePriceSchemeVoList.stream().forEach(scheme -> {
                List<BusHousePriceSchemeLayout> collect = priceSchemeLayouts.stream().
                        filter(schemeLayout -> StrUtil.equals(scheme.getId(), schemeLayout.getSchemeId())).collect(Collectors.toList());
                scheme.setHousePriceSchemeLayoutList(collect);
            });
        }
        return Result.ok(cesHousePriceSchemeVoList);
    }

    public Result listByLayout(CesHousePriceSchemeSearchDto dto) {
        List<CesHousePriceSchemesVo> records = cesHousePriceSchemeMapper.getEffectiveSchemes(dto.getHotelId(),dto.getLayoutId());
        Map<String,Object> map = new HashedMap();
        map.put("records",records);
        return Result.OK(map);
    }

    String _tenantId = "";
    @Transactional(rollbackFor = Exception.class)
    public Result create(CesHousePriceSchemeDto dto) {
        dto.setCreateAt(LocalDateTime.now());
        dto.setUpdateAt(LocalDateTime.now());
        dto.setInvalid(false);
        //查询 - 不能有相同条码的数据
        QueryWrapper<CesHousePriceScheme> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CesHousePriceScheme.NUMBER,dto.getNumber());
        queryWrapper.eq(CesHousePriceScheme.INVALID,false);
        queryWrapper.eq(CesHousePriceScheme.HOTEL_ID,dto.getHotelId());
        CesHousePriceScheme exitModel = cesHousePriceSchemeMapper.selectOne(queryWrapper);
        if(!ObjectUtils.isEmpty(exitModel)) return Result.error("该编号已存在!");

        CesHousePriceScheme cesHousePriceScheme = new CesHousePriceScheme();
        BeanUtil.copyProperties(dto,cesHousePriceScheme);
        cesHousePriceSchemeMapper.insert(cesHousePriceScheme);
        //获取到所有房型
        List<CesRoomLayout> layoutList = cesRoomLayoutMapper.selectList(new QueryWrapper<CesRoomLayout>()
                .eq(CesRoomLayout.HOTEL_ID, dto.getHotelId())
                .eq(CesRoomLayout.INVALID,false));
        List<BusHousePriceSchemeLayout> housePriceSchemeLayouts = new ArrayList<>();
        if (layoutList != null && layoutList.size() >0) {
            LoginUser user = TokenUtils.getAuthUser();
            if(user.getRelTenantIds() != null && !user.getRelTenantIds().equals("")){
                _tenantId = user.getRelTenantIds();
            }
            layoutList.forEach(item -> {
                BusHousePriceSchemeLayout housePriceSchemeLayout = new BusHousePriceSchemeLayout();
                housePriceSchemeLayout.setTenantId(_tenantId);
                housePriceSchemeLayout.setHotelId(cesHousePriceScheme.getHotelId());
                housePriceSchemeLayout.setSchemeId(cesHousePriceScheme.getId());
                housePriceSchemeLayout.setLayoutId(item.getId());
                housePriceSchemeLayout.setMoney(item.getMarketPrice());
                housePriceSchemeLayout.setBreakfastNumber(0);
                housePriceSchemeLayout.setLunchNumber(0);
                housePriceSchemeLayout.setDinnerNumber(0);
                housePriceSchemeLayout.setDelFlag(CommonConstant.DEL_FLAG_0);
                Time time = Time.valueOf("15:00:00");
                housePriceSchemeLayout.setDepartureTime(time);
                housePriceSchemeLayouts.add(housePriceSchemeLayout);
            });
            busHousePriceSchemeLayoutService.saveBatch(housePriceSchemeLayouts);
        }

        return Result.ok("创建成功!");
    }
    /**
     * 修改
     * @param dto
     * @return
     */
    public Result  modify(CesHousePriceSchemeDto dto){
        //查询是否有相同名称的房型
        QueryWrapper<CesHousePriceScheme> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CesHousePriceScheme.HOTEL_ID, dto.getHotelId());
        queryWrapper.eq(CesHousePriceScheme.ID,dto.getId());
        queryWrapper.eq(CesHousePriceScheme.INVALID, false);
        CesHousePriceScheme model = cesHousePriceSchemeMapper.selectOne(queryWrapper);
        if(ObjectUtils.isEmpty(model)) return Result.error("房价方案数据未找到!");
        //忽略空值 不然会覆盖
        BeanUtil.copyProperties(dto,model, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        model.setUpdateAt(LocalDateTime.now());
//        model.setGuestType(dto.getGuestType());
//        cesHousePriceSchemeMapper.updateById(model);
        LambdaUpdateWrapper<CesHousePriceScheme> wrapper = new LambdaUpdateWrapper<>();
        if (dto.getGuestType() == null){
            wrapper.set(CesHousePriceScheme::getGuestType, null);
        }
        wrapper.eq(CesHousePriceScheme::getId, model.getId());
        cesHousePriceSchemeMapper.update(model,wrapper);
        return Result.ok("修改成功!");
    }

    /**
     * 修改状态
     * @param id
     * @param hotelId
     * @param open
     * @return
     */
    public Result modifyOpen(String id,String hotelId, Integer open){
        QueryWrapper<CesHousePriceScheme> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(CesHousePriceScheme.HOTEL_ID, hotelId);
        queryWrapper.eq(CesHousePriceScheme.ID,id);
        queryWrapper.eq(CesHousePriceScheme.INVALID, false);
        CesHousePriceScheme model = cesHousePriceSchemeMapper.selectOne(queryWrapper);
        if(ObjectUtils.isEmpty(model)) return Result.error("房价方案数据未找到!");

        model.setOpen(open);
        model.setUpdateAt(LocalDateTime.now());
        cesHousePriceSchemeMapper.updateById(model);
        return Result.ok("修改成功!");
    }

    public Result deleteOne(String id) {
        CesHousePriceScheme cesHousePriceScheme = cesHousePriceSchemeMapper.selectOne(new QueryWrapper<CesHousePriceScheme>()
                .eq(CesHousePriceScheme.ID, id)
                .eq(CesHousePriceScheme.INVALID, false));
        if (ObjectUtils.isEmpty(cesHousePriceScheme)){
            return Result.ok("删除成功!");
        }
        cesHousePriceScheme.setUpdateAt(LocalDateTime.now());
        cesHousePriceScheme.setInvalid(true);
        cesHousePriceSchemeMapper.updateById(cesHousePriceScheme);
        return  Result.ok("删除成功!");
    }

    public Result batchDelete(List<String> ids) {
        List<CesHousePriceScheme> cesHousePriceSchemes = cesHousePriceSchemeMapper.selectBatchIds(ids);
        if (CollectionUtil.isEmpty(cesHousePriceSchemes)){
            //查不到证明已经被删除过了
            return Result.ok("删除成功!");
        }
        cesHousePriceSchemes.forEach(v->{
            v.setUpdateAt(LocalDateTime.now());
            v.setInvalid(true);
        });
        saveOrUpdateBatch(cesHousePriceSchemes);
        return Result.ok("删除成功!");
    }
}
